#include "core/main.h"

namespace mike
{

static std::map< std::string, std::vector< double > > sDouble;
static std::map< std::string, std::vector< int > >    sInt;

static std::map< std::string, std::vector< std::vector< double > > > sDoubles;
static std::map< std::string, std::vector< std::vector< int > > >    sInts;

//
// append
//
void MatrixWriterAppendDouble( const std::string& channel, const double d )
{
    sDouble[ channel ].push_back( d );
}

void MatrixWriterAppendInt( const std::string& channel, const int i )
{
    sInt[ channel ].push_back( i );
}

void MatrixWriterAppendDoubles( const std::string& channel, const std::vector< double >& doubles )
{
    sDoubles[ channel ].push_back( doubles );
}

void MatrixWriterAppendInts( const std::string& channel, const std::vector< int >& ints )
{
    sInts[ channel ].push_back( ints );
}

//
// clear
//
void MatrixWriterClearChannelDouble( const std::string& channel )
{
    RELEASE_ASSERT( sDouble.count( channel ) != 0 );

    sDouble[ channel ].clear();
}

void MatrixWriterClearChannelInt( const std::string& channel )
{
    RELEASE_ASSERT( sInt.count( channel ) != 0 );

    sInt[ channel ].clear();
}

void MatrixWriterClearChannelDoubles( const std::string& channel )
{
    RELEASE_ASSERT( sDoubles.count( channel ) != 0 );

    sDoubles[ channel ].clear();
}

void MatrixWriterClearChannelInts( const std::string& channel )
{
    RELEASE_ASSERT( sInts.count( channel ) != 0 );

    sInts[ channel ].clear();
}

//
// write to file
//
void MatrixWriterWriteToFileDouble( const std::string& channel, const std::string& fileName )
{
    RELEASE_ASSERT( sDouble.count( channel ) != 0 );

    std::ofstream file;
    file.open( fileName );

    for ( auto row = sDouble[ channel ].begin(), end = sDouble[ channel ].end(); row != end; ++row)
    {
        file << *row << "\n";
    }

    file.close();
}

void MatrixWriterWriteToFileInt( const std::string& channel, const std::string& fileName )
{
    RELEASE_ASSERT( sInt.count( channel ) != 0 );

    std::ofstream file;
    file.open( fileName );

    for ( auto row = sInt[ channel ].begin(), end = sInt[ channel ].end(); row != end; ++row)
    {
        file << *row << "\n";
    }

    file.close();
}

void MatrixWriterWriteToFileDoubles( const std::string& channel, const std::string& fileName )
{
    RELEASE_ASSERT( sDoubles.count( channel ) != 0 );

    std::ofstream file;
    file.open( fileName );

    for ( auto row = sDoubles[ channel ].begin(), end = sDoubles[ channel ].end(); row != end; ++row)
    {
        for ( auto col = (*row).begin(), end = (*row).end(); col != end; ++col)
        {
            file << *col << " ";
        }

        file << "\n";
    }

    file.close();
}

void MatrixWriterWriteToFileInts( const std::string& channel, const std::string& fileName )
{
    RELEASE_ASSERT( sInts.count( channel ) != 0 );

    std::ofstream file;
    file.open( fileName );

    for ( auto row = sInts[ channel ].begin(), end = sInts[ channel ].end(); row != end; ++row)
    {
        for ( auto col = (*row).begin(), end = (*row).end(); col != end; ++col)
        {
            file << *col << " ";
        }

        file << "\n";
    }

    file.close();
}

};